pipeline {
    agent any
    
    tools {
        maven 'maven3.9'
        jdk 'JDK1.8'
    }
    
    parameters {
        string(
            name: 'ImageVersion',
            description: '镜像版本',
            defaultValue: '1.0.0'
        )
        booleanParam(
            name: 'OnlyDeploy', 
            defaultValue: false, 
            description: '是否仅部署前端工程'
        )
    }
    
    environment {
        // 管理平台前端工程名称
        PROJECT_CONSOLE_NAME="nsmd-admin-ui"
        // 大屏平台前端工程名称
        PROJECT_IOC_NAME="nsmd-data-ui"
        // 工程构建镜像和docker镜像名称
        PROEJCT_UI_NAME="nsmd-web-ui"
        // 部署目标主机
        PROJECT_DEPLOY_HOST_NAME="jsproj.szjingshuo.top"
        // compose文件上层目录名称
        PROEJCT_GROUP_NAME="nsmd"

        GIT_REPO_USER_ID="goes_for_jenkins"
        GIT_REPO_CONSOLE_URL="http://git.szjingshuo.top:3000/NSMD/${PROJECT_CONSOLE_NAME}.git"
        GIT_REPO_IOC_URL="http://git.szjingshuo.top:3000/NSMD/${PROJECT_IOC_NAME}.git"
        
        DOCKER_BUILD_HOST_NAME="docker.szjingshuo.top"
        DOCKER_REGISTRY_HOST_NAME="reg.szjingshuo.top"
        DOCKER_IMAGE_NODE_NAME='node:16.15.0-alpine3.15'
        DOCKER_IMAGE_NGINX_NAME='nginx:1.23.4-alpine3.17'
        DOCKER_TEMP_IMG_NAME="${env.PROEJCT_UI_NAME}_tmp:${params.ImageVersion}"
        DOCKER_IMAGE_PROJECT_UI_NAME="${env.DOCKER_REGISTRY_HOST_NAME}/${env.PROEJCT_GROUP_NAME}/${env.PROEJCT_UI_NAME}:${params.ImageVersion}"

        DATE_TIME = sh(returnStdout: true, script: 'date "+%Y%m%d_%H:%M:%S"').trim()
    }

    stages {
        stage("拉取管理平台仓库源码") {
            when {
                expression { params.OnlyDeploy == false }
            }
            steps {
                dir("${env.PROJECT_CONSOLE_NAME}") {
                    echo "开始拉取控制台工程源码，URL=>${env.GIT_REPO_CONSOLE_URL}"
                    git branch:"master", credentialsId: "${env.GIT_REPO_USER_ID}", url:"${env.GIT_REPO_CONSOLE_URL}"
                    echo "代码拉取成功"  
                }
            }
        }
        stage("拉取IOC大屏仓库源码") {
             when {
                expression { params.OnlyDeploy == false }
            }
            steps {
                dir("${env.PROJECT_IOC_NAME}") {
                    echo "开始拉取IOC大屏工程源码，URL=>${env.GIT_REPO_IOC_URL}"
                    git branch:"master", credentialsId: "${env.GIT_REPO_USER_ID}", url:"${env.GIT_REPO_IOC_URL}"
                    echo "代码拉取成功"
                }
            }
        }
        stage("开始构建前端工程应用镜像") {
            steps {
                sshPublisher(
                    publishers: [
                        sshPublisherDesc(
                            configName: "${env.DOCKER_BUILD_HOST_NAME}", 
                            transfers: [
                                //复制Console前端源码至Docker构建服务器,并开始构建
                                sshTransfer(
                                    execTimeout: 240000, 
                                    remoteDirectory: "/tmp/${env.PROJECT_CONSOLE_NAME}", 
                                    removePrefix: "${env.PROJECT_CONSOLE_NAME}", 
                                    sourceFiles: "${env.PROJECT_CONSOLE_NAME}/**",
                                    exclude: ".git/**",
                                    execCommand: """
                                        # 判断Node基础镜像是否存在，如果不存在则先下载
                                        if [[ "" == "\$(docker images -q ${env.DOCKER_IMAGE_NODE_NAME} 2> /dev/null)" ]];then
                                            echo "开始下载NodeJS基础镜像${env.DOCKER_IMAGE_NODE_NAME}"
                                            docker pull ${env.DOCKER_IMAGE_NODE_NAME}
                                            echo "NodeJS基础镜像下载完成"
                                        fi
                                        if [[ "" == "\$(docker images -q ${env.DOCKER_IMAGE_NGINX_NAME} 2> /dev/null)" ]];then
                                            echo "开始下载NodeJS基础镜像${env.DOCKER_IMAGE_NGINX_NAME}"
                                            docker pull ${env.DOCKER_IMAGE_NGINX_NAME}
                                            echo "Nginx基础镜像下载完成"
                                        fi
                                        echo "开始构建Console前端工程"
                                        docker build -t ${DOCKER_TEMP_IMG_NAME} /tmp/${env.PROJECT_CONSOLE_NAME}
                                        echo "Console前端工程镜像构建完成"
                                        # 删除之前同版本镜像
                                        if [[ "" == "\$(docker images -q ${DOCKER_TEMP_IMG_NAME} 2> /dev/null)" ]];then
                                            echo "镜像【${DOCKER_TEMP_IMG_NAME}】已存在，将删除后重新上传"
                                            docker rmi ${DOCKER_TEMP_IMG_NAME}
                                            echo "镜像【${DOCKER_TEMP_IMG_NAME}】删除成功"
                                        fi
                                        # 删除临时文件
                                        rm -rf /tmp/${PROJECT_CONSOLE_NAME}
                                    """
                                ), 
                                //复制IOC前端源码至Docker构建服务器,并开始构建
                                sshTransfer(
                                    execTimeout: 240000, 
                                    remoteDirectory: "/tmp/${env.PROJECT_IOC_NAME}", 
                                    removePrefix: "${env.PROJECT_IOC_NAME}", 
                                    sourceFiles: "${env.PROJECT_IOC_NAME}/**",
                                    exclude: ".git/**",
                                    execCommand: """
                                        echo "修改IOC镜像构建脚本"
                                        sed -i "s#FROM.*reg.szjingshuo.top.*#FROM ${DOCKER_TEMP_IMG_NAME}#g" /tmp/${env.PROJECT_IOC_NAME}/Dockerfile
                                        echo "开始基于镜像【${DOCKER_TEMP_IMG_NAME}】开始构建IOC镜像"
                                        docker build -t ${DOCKER_IMAGE_PROJECT_UI_NAME} /tmp/${env.PROJECT_IOC_NAME}
                                        echo "IOC前端代码已整合至镜像【${DOCKER_IMAGE_PROJECT_UI_NAME}】"
                                        echo "开始推送镜像【${DOCKER_IMAGE_PROJECT_UI_NAME}】至镜像仓库"
                                        docker push ${DOCKER_IMAGE_PROJECT_UI_NAME}
                                        echo "镜像【${DOCKER_IMAGE_PROJECT_UI_NAME}】已推送至镜像仓库"
                                        # 删除临时镜像
                                        docker rmi ${DOCKER_TEMP_IMG_NAME}
                                        # 删除前端镜像
                                        docker rmi ${DOCKER_IMAGE_PROJECT_UI_NAME}
                                        # 删除前端工程源文件
                                        rm -rf /tmp/${env.PROJECT_IOC_NAME}
                                    """
                                )
                            ],
                            verbose: true
                        )
                    ]
                )
                echo "前端工程应用镜像构建完成"
            }
        }
        stage("部署前端DockerCompose文件") {
            steps {
                sshPublisher(
                    publishers: [
                        sshPublisherDesc(
                            configName: "${env.PROJECT_DEPLOY_HOST_NAME}", 
                            transfers: [
                                //复制Console前端源码至Docker构建服务器,并开始构建
                                sshTransfer(
                                    execTimeout: 120000, 
                                    remoteDirectory: "/tmp/${env.PROJECT_CONSOLE_NAME}", 
                                    removePrefix: "${env.PROJECT_CONSOLE_NAME}", 
                                    sourceFiles: "${env.PROJECT_CONSOLE_NAME}/docker-compose.yaml",
                                    exclude: ".git/**",
                                    execCommand: """
                                        if [[ -e /tmp/${PROJECT_CONSOLE_NAME}/docker-compose.yaml ]];then
                                            if [[ ! -d /opt/${PROEJCT_GROUP_NAME} ]];then
                                                mkdir -p /opt/${PROEJCT_GROUP_NAME}
                                                echo "目录【/opt/${PROEJCT_GROUP_NAME}】创建成功"
                                            fi
                                            # 先停止compose中全部服务，避免新文件内容改变导致原服务停止不彻底
                                            if [[ \$(docker-compose ls | grep -q frontend-service) ]];then
                                                docker-compose -f /opt/${PROEJCT_GROUP_NAME}/frontend-service.yaml down
                                                echo "前端服务已停止"
                                            fi
                                            #删除旧部署文件
                                            if [[ -e "/opt/${PROEJCT_GROUP_NAME}/frontend-service.yaml" ]];then
                                                rm -f /opt/${PROEJCT_GROUP_NAME}/frontend-service.yaml
                                                echo "旧版本前端部署文件删除完毕"
                                            fi
                                            # 生成新的compose文件
                                            cp /tmp/${PROJECT_CONSOLE_NAME}/docker-compose.yaml /opt/${PROEJCT_GROUP_NAME}/frontend-service.yaml
                                            # 修改前端拉取镜像名称和版本信息
                                            sed -i "s#image:.*${DOCKER_REGISTRY_HOST_NAME}.*#image: ${DOCKER_IMAGE_PROJECT_UI_NAME}#g" /opt/${PROEJCT_GROUP_NAME}/frontend-service.yaml
                                            echo "前端部署文件更新完成"
                                            echo "前端部署文件已安装至【/opt/${PROEJCT_GROUP_NAME}/frontend-service.yaml】"
                                        fi
                                        # 启动前端服务
                                        docker-compose -f /opt/${PROEJCT_GROUP_NAME}/frontend-service.yaml up -d
                                        echo "前端服务已启动"
                                        # 删除临时文件
                                        rm -rf /tmp/${PROJECT_CONSOLE_NAME}
                                    """
                                )
                            ],
                            verbose: true
                        )
                    ]
                )
                echo "前端工程部署完成"
            }
        }
    }
}